package com.voe;

import com.voe.callback.VoERxVadCallback;
import com.voe.common.AecmModes;
import com.voe.common.AgcConfig;
import com.voe.common.AgcModes;
import com.voe.common.EcModes;
import com.voe.common.NsModes;
import com.voe.common.OutputParam;
import com.voe.common.ReturnValue;
import com.voe.common.Utility;

/** This sub-API supports the following functionalities:<br/>
*<br/>
*- Noise Suppression (NS).<br/>
*- Automatic Gain Control (AGC).<br/>
*- Echo Control (EC).<br/>
*- Receiving side VAD, NS and AGC.<br/>
*- Measurements of instantaneous speech, noise and echo levels.<br/>
*- Generation of AP debug recordings.<br/>
*- Detection of keyboard typing which can disrupt a voice conversation.<br/>
*<br/>
*Usage example, omitting error checking:<br/>
*<br/>
*VoiceEngine voe = VoiceEngine.createInstance();<br/>
*VoEBase base = VoEBase.createInstance(voe);<br/>
*VoEAudioProcessing ap = VoEAudioProcessing.createInstance(voe);<br/>
*base.init();<br/>
*ap.setAgcStatus(true, AgcModes.kAgcAdaptiveAnalog);<br/>
*...<br/>
*base.terminate();<br/>
*base.release();<br/>
*ap.release();<br/>
*voe.release();<br/>
*/
public class VoEAudioProcessing {

	// [start] apis
	
	public static VoEAudioProcessing createInstance(VoiceEngine voiceEngine) {

		long p = GetInterface(voiceEngine._p);
		if(p != 0)
			return new VoEAudioProcessing(p);
		return null;
	}

	public void release() {
		if (_p != 0) {
			Release(_p);
		}
	}

	/** Sets Noise Suppression (NS) status and mode.<br/>
	 * The NS reduces noise in the microphone signal.
	 */ 
	public int setNsStatus(boolean enable, NsModes mode) {
		return SetNsStatus(_p, enable, mode.getValue());
	}

	/** Sets Noise Suppression (NS) status and mode.<br/>
	 * The NS reduces noise in the microphone signal.
	 */ 
	public int setNsStatus(boolean enable) {
		return setNsStatus(enable, NsModes.kNsUnchanged);
	}

	/** Gets the NS status and mode.
	 * 
	 */
	public int getNsStatus(ReturnValue<Boolean> enabled,
			ReturnValue<NsModes> mode) {
		OutputParam output = new OutputParam();
		int result = GetNsStatus(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
			mode.setValue(NsModes.fromValue((Integer) output.getObject()[1]));
		}
		return result;
	}

	/** Sets the Automatic Gain Control (AGC) status and mode.<br/>
	 *  The AGC adjusts the microphone signal to an appropriate level.
	 */
	public int setAgcStatus(boolean enable, AgcModes mode) {
		return SetAgcStatus(_p, enable, mode.getValue());
	}

	/** Sets the Automatic Gain Control (AGC) status and mode.<br/>
	 *  The AGC adjusts the microphone signal to an appropriate level.
	 */
	public int setAgcStatus(boolean enable) {
		return setAgcStatus(enable, AgcModes.kAgcUnchanged);
	}

	/** Gets the AGC status and mode.
	 * 
	 */
	public int getAgcStatus(ReturnValue<Boolean> enabled,
			ReturnValue<AgcModes> mode) {
		OutputParam output = new OutputParam();
		int result = GetAgcStatus(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
			mode.setValue(AgcModes.fromValue((Integer) output.getObject()[1]));
		}
		return result;
	}

	/** Sets the AGC configuration.
	 *  Should only be used in situations where the working environment
	 *  is well known.
	 */
	public int setAgcConfig(AgcConfig config) {
		return SetAgcConfig(_p, config.targetLeveldBOv,
				config.digitalCompressionGaindB, config.limiterEnable);
	}

	/** Gets the AGC configuration.
	 * 
	 */
	public int getAgcConfig(ReturnValue<AgcConfig> config) {
		OutputParam output = new OutputParam();
		int result = GetAgcConfig(_p, output);
		if(result == 0) {
			AgcConfig tmp = new AgcConfig();
			tmp.targetLeveldBOv = ((Integer) output.getObject()[0]).shortValue();
			tmp.digitalCompressionGaindB = ((Integer) output.getObject()[1])
					.shortValue();
			tmp.limiterEnable = (Boolean) output.getObject()[2];
			config.setValue(tmp);
		}
		return result;
	}

	/** Sets the Echo Control (EC) status and mode.<br/>
	 *  The EC mitigates acoustic echo where a user can hear their own<br/>
	 *  speech repeated back due to an acoustic coupling between the<br/>
	 *  speaker and the microphone at the remote end.<br/>
	 */
	public int setEcStatus(boolean enable, EcModes mode) {
		return SetEcStatus(_p, enable, mode.getValue());
	}

	/** Sets the Echo Control (EC) status and mode.<br/>
	 *  The EC mitigates acoustic echo where a user can hear their own<br/>
	 *  speech repeated back due to an acoustic coupling between the<br/>
	 *  speaker and the microphone at the remote end.<br/>
	 */
	public int setEcStatus(boolean enable) {
		return setEcStatus(enable, EcModes.kEcUnchanged);
	}

	// Gets the EC status and mode.
	public int getEcStatus(ReturnValue<Boolean> enabled,
			ReturnValue<EcModes> mode) {
		OutputParam output = new OutputParam();
		int result = GetEcStatus(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
			mode.setValue(EcModes.fromValue((Integer) output.getObject()[1]));
		}
		return result;
	}

	/** Enables the compensation of clock drift between the capture and render<br/>
	 *  streams by the echo canceller (i.e. only using EcMode==kEcAec). It will<br/>
	 *  only be enabled if supported on the current platform; otherwise an error<br/>
	 *  will be returned. Check if the platform is supported by calling<br/>
	 *  |DriftCompensationSupported()|.
	 */ 
	public int enableDriftCompensation(boolean enable) {
		return EnableDriftCompensation(_p, enable);
	}

	public boolean driftCompensationEnabled() {
		return DriftCompensationEnabled(_p);
	}

	public boolean driftCompensationSupported() {
		return DriftCompensationSupported(_p);
	}

	/** Sets a delay |offset| in ms to add to the system delay reported by the<br/>
	 *  OS, which is used by the AEC to synchronize far- and near-end streams.<br/>
	 *  In some cases a system may introduce a delay which goes unreported by the<br/>
	 *  OS, but which is known to the user. This method can be used to compensate<br/>
	 *  for the unreported delay.
	 */
	public void setDelayOffsetMs(int offset) {
		SetDelayOffsetMs(_p, offset);
	}

	public int delayOffsetMs() {
		return DelayOffsetMs(_p);
	}

	/** Modifies settings for the AEC designed for mobile devices (AECM).
	 * 
	 */
	public int setAecmMode(AecmModes mode, boolean enableCNG) {
		return SetAecmMode(_p, mode.getValue(), enableCNG);
	}

	/** Modifies settings for the AEC designed for mobile devices (AECM).
	 * 
	 */
	public int setAecmMode(AecmModes mode) {
		return setAecmMode(mode, true);
	}

	/** Modifies settings for the AEC designed for mobile devices (AECM).
	 * 
	 */
	public int setAecmMode() {
		return setAecmMode(AecmModes.kAecmSpeakerphone, true);
	}

	/** Gets settings for the AECM.
	 * 
	 */
	public int getAecmMode(ReturnValue<Boolean> enabled,
			ReturnValue<AecmModes> mode) {
		OutputParam output = new OutputParam();
		int result = GetAecmMode(_p, output);
		if(result == 0) {
			mode.setValue(AecmModes.fromValue((Integer) output.getObject()[0]));
			enabled.setValue((Boolean) output.getObject()[1]);
		}
		return result;
	}

	/** Enables a high pass filter on the capture signal. This removes DC bias<br/>
	 *  and low-frequency noise. Recommended to be enabled.
	 */
	public int enableHighPassFilter(boolean enable) {
		return EnableHighPassFilter(_p, enable);
	}

	public boolean isHighPassFilterEnabled() {
		return IsHighPassFilterEnabled(_p);
	}

	/** Sets status and mode of the receiving-side (Rx) NS.<br/>
	 *  The Rx NS reduces noise in the received signal for the specified<br/>
	 *  |channel|. Intended for advanced usage only.<br/>
	 */
	public int setRxNsStatus(int channel, boolean enable, NsModes mode) {
		return SetRxNsStatus(_p, channel, enable, mode.getValue());
	}

	/** Sets status and mode of the receiving-side (Rx) NS.<br/>
	 *  The Rx NS reduces noise in the received signal for the specified<br/>
	 *  |channel|. Intended for advanced usage only.<br/>
	 */
	public int setRxNsStatus(int channel, boolean enable) {
		return setRxNsStatus(channel, enable, NsModes.kNsUnchanged);
	}

	/** Gets status and mode of the receiving-side NS.
	 * 
	 */
	public int getRxNsStatus(int channel, ReturnValue<Boolean> enabled,
			ReturnValue<NsModes> mode) {
		OutputParam output = new OutputParam();
		int result = GetRxNsStatus(_p, channel, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
			mode.setValue(NsModes.fromValue((Integer) output.getObject()[1]));
		}
		return result;
	}

	/** Sets status and mode of the receiving-side (Rx) AGC.<br/>
	 *  The Rx AGC adjusts the received signal to an appropriate level<br/>
	 *  for the specified |channel|. Intended for advanced usage only.
	 */
	public int setRxAgcStatus(int channel, boolean enable, AgcModes mode) {
		return SetRxAgcStatus(_p, channel, enable, mode.getValue());
	}

	/** Sets status and mode of the receiving-side (Rx) AGC.<br/>
	 *  The Rx AGC adjusts the received signal to an appropriate level<br/>
	 *  for the specified |channel|. Intended for advanced usage only.
	 */
	public int setRxAgcStatus(int channel, boolean enable) {
		return setRxAgcStatus(channel, enable, AgcModes.kAgcUnchanged);
	}

	/** Gets status and mode of the receiving-side AGC.
	 * 
	 */
	public int getRxAgcStatus(int channel, ReturnValue<Boolean> enabled,
			ReturnValue<AgcModes> mode) {
		OutputParam output = new OutputParam();
		int result = GetRxAgcStatus(_p, channel, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
			mode.setValue(AgcModes.fromValue((Integer) output.getObject()[1]));
		}
		return result;
	}

	/** Modifies the AGC configuration on the receiving side for the<br/>
	 *  specified |channel|.
	 */
	public int setRxAgcConfig(int channel, AgcConfig config) {
		return SetRxAgcConfig(_p, channel, config.targetLeveldBOv,
				config.digitalCompressionGaindB, config.limiterEnable);
	}

	/** Gets the AGC configuration on the receiving side.
	 * 
	 */
	public int getRxAgcConfig(int channel, ReturnValue<AgcConfig> config) {
		OutputParam output = new OutputParam();
		int result = GetRxAgcConfig(_p, channel, output);
		if(result == 0) {
			AgcConfig tmp = new AgcConfig();
			tmp.targetLeveldBOv = ((Integer) output.getObject()[0]).shortValue();
			tmp.digitalCompressionGaindB = ((Integer) output.getObject()[1])
					.shortValue();
			tmp.limiterEnable = (Boolean) output.getObject()[2];
			config.setValue(tmp);
		}
		return result;
	}

	/** Registers a VoERxVadCallback |observer| instance and enables Rx VAD<br/>
	 *  notifications for the specified |channel|.
	 */
	public int registerRxVadObserver(int channel, VoERxVadCallback observer) {
		Utility.throwNullPointerException(observer, "observer");
		return RegisterRxVadObserver(_p, channel, observer);
	}

	/** Deregisters the VoERxVadCallback |observer| and disables Rx VAD<br/>
	 *  notifications for the specified |channel|.<br/>
	 */
	public int deRegisterRxVadObserver(int channel) {
		return DeRegisterRxVadObserver(_p, channel);
	}

	/** Gets the VAD/DTX activity for the specified |channel|.<br/>
	 *  The returned value is 1 if frames of audio contains speech<br/>
	 *  and 0 if silence. The output is always 1 if VAD is disabled.
	 */
	public int voiceActivityIndicator(int channel) {
		return VoiceActivityIndicator(_p, channel);
	}

	/** Enables or disables the possibility to retrieve echo metrics and delay<br/>
	 *  logging values during an active call. The metrics are only supported in<br/>
	 *  AEC.
	 */
	public int setEcMetricsStatus(boolean enable) {
		return SetEcMetricsStatus(_p, enable);
	}

	/** Gets the current EC metric status.
	 */
	public int getEcMetricsStatus(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetEcMetricsStatus(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
		}
		return result;
	}

	/** Gets the instantaneous echo level metrics.
	 */
	public int getEchoMetrics(ReturnValue<Integer> ERL,
			ReturnValue<Integer> ERLE, ReturnValue<Integer> RERL,
			ReturnValue<Integer> A_NLP) {
		OutputParam output = new OutputParam();
		int result = GetEchoMetrics(_p, output);
		if(result == 0) {
			ERL.setValue((Integer) output.getObject()[0]);
			ERLE.setValue((Integer) output.getObject()[1]);
			RERL.setValue((Integer) output.getObject()[2]);
			A_NLP.setValue((Integer) output.getObject()[3]);
		}
		return result;
	}

	/** Gets the EC internal |delay_median| and |delay_std| in ms between<br/>
	 *  near-end and far-end. The values are calculated over the time period<br/>
	 *  since the last GetEcDelayMetrics() call.
	 */
	public int getEcDelayMetrics(ReturnValue<Integer> delay_median,
			ReturnValue<Integer> delay_std) {
		OutputParam output = new OutputParam();
		int result = GetEcDelayMetrics(_p, output);
		if(result == 0) {
			delay_median.setValue((Integer) output.getObject()[0]);
			delay_std.setValue((Integer) output.getObject()[1]);
		}
		return result;
	}

	/** Enables recording of Audio Processing (AP) debugging information.<br/>
	 *  The file can later be used for off-line analysis of the AP performance.
	 */
	public int startDebugRecording(String fileNameUTF8) {
		return StartDebugRecording(_p, fileNameUTF8);
	}

	/** Disables recording of AP debugging information.
	 */
	public int stopDebugRecording() {
		return StopDebugRecording(_p);
	}

	/** Enables or disables detection of disturbing keyboard typing.<br/>
	 *  An error notification will be given as a callback upon detection.
	 */
	public int setTypingDetectionStatus(boolean enable) {
		return SetTypingDetectionStatus(_p, enable);
	}

	/** Gets the current typing detection status.
	 */
	public int getTypingDetectionStatus(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetTypingDetectionStatus(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean) output.getObject()[0]);
		}
		return result;
	}

	/** Reports the lower of:<br/>
	 *  * Time in seconds since the last typing event.<br/>
	 *  * Time in seconds since the typing detection was enabled.<br/>
	 *  Returns error if typing detection is disabled.
	 */
	public int timeSinceLastTyping(ReturnValue<Integer> seconds) {
		OutputParam output = new OutputParam();
		int result = TimeSinceLastTyping(_p, output);
		if(result == 0) {
			seconds.setValue((Integer) output.getObject()[0]);
		}
		return result;
	}

	/** Optional setting of typing detection parameters<br/>
	 *  Parameter with value == 0 will be ignored<br/>
	 *  and left with default config.<br/>
	 *  TODO(niklase) Remove default argument as soon as libJingle is updated!
	 */
	public int setTypingDetectionParameters(int timeWindow, int costPerTyping,
			int reportingThreshold, int penaltyDecay, int typeEventDelay) {
		return SetTypingDetectionParameters(_p, timeWindow, costPerTyping,
				reportingThreshold, penaltyDecay, typeEventDelay);
	}

	/** Optional setting of typing detection parameters<br/>
	 *  Parameter with value == 0 will be ignored<br/>
	 *  and left with default config.<br/>
	 *  TODO(niklase) Remove default argument as soon as libJingle is updated!
	 */
	public int setTypingDetectionParameters(int timeWindow, int costPerTyping,
			int reportingThreshold, int penaltyDecay) {
		return setTypingDetectionParameters(timeWindow, costPerTyping,
				reportingThreshold, penaltyDecay, 0);
	}

	/** Swaps the capture-side left and right audio channels when enabled. It<br/>
	 *  only has an effect when using a stereo send codec. The setting is<br/>
	 *  persistent; it will be applied whenever a stereo send codec is enabled.<br/>
	 *  <br/>
	 *  The swap is applied only to the captured audio, and not mixed files. The<br/>
	 *  swap will appear in file recordings and when accessing audio through the<br/>
	 *  external media interface.
	 */
	public void enableStereoChannelSwapping(boolean enable) {
		EnableStereoChannelSwapping(_p, enable);
	}

	public boolean isStereoChannelSwappingEnabled() {
		return IsStereoChannelSwappingEnabled(_p);
	}

	protected VoEAudioProcessing(long p) {
		_p = p;
	}

	protected long _p;

	
	// [end]
	
	
	
	
	
	
	
	
	
	// [start] jni api

	// Factory for the VoEAudioProcessing sub-API. Increases an internal
	// reference counter if successful. Returns NULL if the API is not
	// supported or if construction fails.
	private static native long GetInterface(long p_voiceEngine);

	// Releases the VoEAudioProcessing sub-API and decreases an internal
	// reference counter. Returns the new reference count. This value should
	// be zero for all sub-API:s before the VoiceEngine object can be safely
	// deleted.
	private static native int Release(long p_VoEAudioProcessing);

	// Sets Noise Suppression (NS) status and mode.
	// The NS reduces noise in the microphone signal.
	private static native int SetNsStatus(long p_VoEAudioProcessing,
			boolean enable, int mode);

	// Gets the NS status and mode.
	private static native int GetNsStatus(long p_VoEAudioProcessing,
			OutputParam param);

	// Sets the Automatic Gain Control (AGC) status and mode.
	// The AGC adjusts the microphone signal to an appropriate level.
	private static native int SetAgcStatus(long p_VoEAudioProcessing,
			boolean enable, int mode);

	// Gets the AGC status and mode.
	private static native int GetAgcStatus(long p_VoEAudioProcessing,
			OutputParam param);

	// Sets the AGC configuration.
	// Should only be used in situations where the working environment
	// is well known.
	private static native int SetAgcConfig(long p_VoEAudioProcessing,
			short targetLeveldBOv, short digitalCompressionGaindB,
			boolean limiterEnable);

	// Gets the AGC configuration.
	private static native int GetAgcConfig(long p_VoEAudioProcessing,
			OutputParam config);

	// Sets the Echo Control (EC) status and mode.
	// The EC mitigates acoustic echo where a user can hear their own
	// speech repeated back due to an acoustic coupling between the
	// speaker and the microphone at the remote end.
	private static native int SetEcStatus(long p_VoEAudioProcessing,
			boolean enable, int mode);

	// Gets the EC status and mode.
	private static native int GetEcStatus(long p_VoEAudioProcessing,
			OutputParam param);

	// Enables the compensation of clock drift between the capture and render
	// streams by the echo canceller (i.e. only using EcMode==kEcAec). It will
	// only be enabled if supported on the current platform; otherwise an error
	// will be returned. Check if the platform is supported by calling
	// |DriftCompensationSupported()|.
	private static native int EnableDriftCompensation(
			long p_VoEAudioProcessing, boolean enable);

	private static native boolean DriftCompensationEnabled(
			long p_VoEAudioProcessing);

	private static native boolean DriftCompensationSupported(
			long p_VoEAudioProcessing);

	// Sets a delay |offset| in ms to add to the system delay reported by the
	// OS, which is used by the AEC to synchronize far- and near-end streams.
	// In some cases a system may introduce a delay which goes unreported by the
	// OS, but which is known to the user. This method can be used to compensate
	// for the unreported delay.
	private static native void SetDelayOffsetMs(long p_VoEAudioProcessing,
			int offset);

	private static native int DelayOffsetMs(long p_VoEAudioProcessing);

	// Modifies settings for the AEC designed for mobile devices (AECM).
	private static native int SetAecmMode(long p_VoEAudioProcessing, int mode,
			boolean enableCNG);

	// Gets settings for the AECM.
	private static native int GetAecmMode(long p_VoEAudioProcessing,
			OutputParam param);

	// Enables a high pass filter on the capture signal. This removes DC bias
	// and low-frequency noise. Recommended to be enabled.
	private static native int EnableHighPassFilter(long p_VoEAudioProcessing,
			boolean enable);

	private static native boolean IsHighPassFilterEnabled(
			long p_VoEAudioProcessing);

	// Sets status and mode of the receiving-side (Rx) NS.
	// The Rx NS reduces noise in the received signal for the specified
	// |channel|. Intended for advanced usage only.
	private static native int SetRxNsStatus(long p_VoEAudioProcessing,
			int channel, boolean enable, int mode);

	// Gets status and mode of the receiving-side NS.
	private static native int GetRxNsStatus(long p_VoEAudioProcessing,
			int channel, OutputParam param);

	// Sets status and mode of the receiving-side (Rx) AGC.
	// The Rx AGC adjusts the received signal to an appropriate level
	// for the specified |channel|. Intended for advanced usage only.
	private static native int SetRxAgcStatus(long p_VoEAudioProcessing,
			int channel, boolean enable, int mode);

	// Gets status and mode of the receiving-side AGC.
	private static native int GetRxAgcStatus(long p_VoEAudioProcessing,
			int channel, OutputParam param);

	// Modifies the AGC configuration on the receiving side for the
	// specified |channel|.
	private static native int SetRxAgcConfig(long p_VoEAudioProcessing,
			int channel, short targetLeveldBOv, short digitalCompressionGaindB,
			boolean limiterEnable);

	// Gets the AGC configuration on the receiving side.
	private static native int GetRxAgcConfig(long p_VoEAudioProcessing,
			int channel, OutputParam config);

	// Registers a VoERxVadCallback |observer| instance and enables Rx VAD
	// notifications for the specified |channel|.
	private static native int RegisterRxVadObserver(long p_VoEAudioProcessing,
			int channel, VoERxVadCallback observer);

	// Deregisters the VoERxVadCallback |observer| and disables Rx VAD
	// notifications for the specified |channel|.
	private static native int DeRegisterRxVadObserver(
			long p_VoEAudioProcessing, int channel);

	// Gets the VAD/DTX activity for the specified |channel|.
	// The returned value is 1 if frames of audio contains speech
	// and 0 if silence. The output is always 1 if VAD is disabled.
	private static native int VoiceActivityIndicator(long p_VoEAudioProcessing,
			int channel);

	// Enables or disables the possibility to retrieve echo metrics and delay
	// logging values during an active call. The metrics are only supported in
	// AEC.
	private static native int SetEcMetricsStatus(long p_VoEAudioProcessing,
			boolean enable);

	// Gets the current EC metric status.
	private static native int GetEcMetricsStatus(long p_VoEAudioProcessing,
			OutputParam enabled);

	// Gets the instantaneous echo level metrics.
	private static native int GetEchoMetrics(long p_VoEAudioProcessing,
			OutputParam param);

	// Gets the EC internal |delay_median| and |delay_std| in ms between
	// near-end and far-end. The values are calculated over the time period
	// since the last GetEcDelayMetrics() call.
	private static native int GetEcDelayMetrics(long p_VoEAudioProcessing,
			OutputParam param);

	// Enables recording of Audio Processing (AP) debugging information.
	// The file can later be used for off-line analysis of the AP performance.
	private static native int StartDebugRecording(long p_VoEAudioProcessing,
			String fileNameUTF8);

	// Disables recording of AP debugging information.
	private static native int StopDebugRecording(long p_VoEAudioProcessing);

	// Enables or disables detection of disturbing keyboard typing.
	// An error notification will be given as a callback upon detection.
	private static native int SetTypingDetectionStatus(
			long p_VoEAudioProcessing, boolean enable);

	// Gets the current typing detection status.
	private static native int GetTypingDetectionStatus(
			long p_VoEAudioProcessing, OutputParam enabled);

	// Reports the lower of:
	// * Time in seconds since the last typing event.
	// * Time in seconds since the typing detection was enabled.
	// Returns error if typing detection is disabled.
	private static native int TimeSinceLastTyping(long p_VoEAudioProcessing,
			OutputParam param);

	// Optional setting of typing detection parameters
	// Parameter with value == 0 will be ignored
	// and left with default config.
	// TODO(niklase) Remove default argument as soon as libJingle is updated!
	private static native int SetTypingDetectionParameters(
			long p_VoEAudioProcessing, int timeWindow, int costPerTyping,
			int reportingThreshold, int penaltyDecay, int typeEventDelay);

	// Swaps the capture-side left and right audio channels when enabled. It
	// only has an effect when using a stereo send codec. The setting is
	// persistent; it will be applied whenever a stereo send codec is enabled.
	//
	// The swap is applied only to the captured audio, and not mixed files. The
	// swap will appear in file recordings and when accessing audio through the
	// external media interface.
	private static native void EnableStereoChannelSwapping(
			long p_VoEAudioProcessing, boolean enable);

	private static native boolean IsStereoChannelSwappingEnabled(
			long p_VoEAudioProcessing);

	// [end]
}
